package com.yami.shop.im.socket;

import cn.hutool.core.util.StrUtil;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.Json;
import com.yami.shop.im.bean.ImRecord;
import com.yami.shop.im.bo.ShopSessionInfo;
import com.yami.shop.im.bo.SysSessionInfo;
import com.yami.shop.im.bo.UserSessionInfo;
import com.yami.shop.im.hanlder.SecurityHandler;
import com.yami.shop.im.param.MessageInfo;
import com.yami.shop.im.service.ImRecordService;
import com.yami.shop.im.vo.MsgItem;
import com.yami.shop.security.multishop.model.YamiShopUser;
import com.yami.shop.security.platform.model.YamiSysUser;
import com.yami.shop.service.ShopDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 商家收到的消息
 * @author LGH
 */
@ServerEndpoint("/im/websocket/platform/{token}")
@Component
@Slf4j
public class PlatformWebSocketServer {

    /**
     * userId为key
     */
    public static final ConcurrentHashMap<Long, SysSessionInfo> SYS_MAP = new ConcurrentHashMap<>(256);

    private static SecurityHandler securityHandler;

    private static ImRecordService imRecordService;


    public static void setApplicationContext(ApplicationContext applicationContext) {
        securityHandler = applicationContext.getBean(SecurityHandler.class);
        imRecordService = applicationContext.getBean(ImRecordService.class);
    }
    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("token") String token) throws IOException {
        log.info("创建连接");
        YamiSysUser sysUser = securityHandler.getSysUser(token);
        if (sysUser == null) {
            session.getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.fail(10,"无法获取用户信息")));
            return;
        }

//        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopUser.getShopId());

        // 如果原来就有token
        SysSessionInfo oldSysSessionInfo = SYS_MAP.get(sysUser.getUserId());
        if (oldSysSessionInfo != null) {
            // 客户端收到11，关闭ws链接，弹出提示
            if (oldSysSessionInfo.getSession().isOpen()) {
                oldSysSessionInfo.getSession().getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.fail(11,"账户已在别处登录，请刷新")));
                oldSysSessionInfo.getSession().close();
            }
        }

        SysSessionInfo sysSessionInfo = new SysSessionInfo();
        sysSessionInfo.setUserName(sysUser.getUsername());
        sysSessionInfo.setUserId(sysUser.getUserId());
        sysSessionInfo.setSession(session);

        SYS_MAP.put(sysSessionInfo.getUserId(), sysSessionInfo);
        session.getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.success()));

    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session,@PathParam("token") String token) {
        log.info("关闭连接");
        YamiSysUser yamiSysUser = securityHandler.getSysUser(token);
        if (yamiSysUser == null) {
            return;
        }
        SYS_MAP.remove(yamiSysUser.getUserId());
    }

    /**
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session,@PathParam("token") String token, Throwable error) {

        log.error("发生错误");
        error.printStackTrace();

        YamiSysUser yamiSysUser = securityHandler.getSysUser(token);
        if (yamiSysUser == null) {
            return;
        }
        SYS_MAP.remove(yamiSysUser.getUserId());
    }

    /**
     * 收到客户端消息后调用的方法，该消息由用户发过来
     *
     * @param sourceMessage
     *            客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String sourceMessage,@PathParam("token") String token, Session session) throws IOException {
        if (StrUtil.isBlank(sourceMessage)) {
            session.getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.fail(13,"内容格式有误")));
            return;
        }

        MessageInfo messageInfo = Json.parseObject(sourceMessage, MessageInfo.class);
        if (messageInfo == null) {
            session.getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.fail(13,"内容格式有误")));
            return;
        }

        // from user info
        YamiSysUser sysUser = securityHandler.getSysUser(token);
        if (sysUser == null) {
            log.error("无法获取用户信息");
            session.getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.fail(10,"无法获取用户信息")));
            return;
        }

        Integer msgType = messageInfo.getMsgType();
        log.info("sourceMessage: " + sourceMessage);


//        // 3天内和各个人的聊天记录
//        if (Objects.equals(MsgType.CONVERSATIONS.value(), msgType)) {
//            // 3天内的聊天记录
//            List<Conversation> conversations = imRecordService.listConversationByShopId(shopUser.getShopId(), 3);
//            // 发给前端聊天记录
//            session.getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.success(conversations)));
//            return;
//        }


        UserSessionInfo userSessionInfo = UserWebSocketServer.USER_MAP.get(messageInfo.getToId());

        // 保存聊天记录
        ImRecord imRecord = new ImRecord();
        imRecord.setUserId(messageInfo.getToId());
        imRecord.setContent(messageInfo.getContent());
        imRecord.setCreateTime(new Date());
        imRecord.setBizId(sysUser.getUserId());
        imRecord.setSendType(1);
        imRecord.setSource(2);
        imRecord.setType(messageInfo.getMsgType());
        imRecord.setIsRead(userSessionInfo == null?0:1);
        imRecordService.save(imRecord);

        // 对方不在线，
        if (userSessionInfo == null) {
            session.getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.fail(12)));
            return;
        }

        SysSessionInfo sysSessionInfo = SYS_MAP.get(sysUser.getUserId());


//        // 和某人的聊天历史记录
//        if (Objects.equals(MsgType.HISTORY.value(), msgType)) {
//            List<ImRecord> imRecords = imRecordService.listHistory(shopSessionInfo.getShopId(), userSessionInfo.getUserId(), 20);
//            List<MsgItem> msgItems = new ArrayList<>();
//            for (ImRecord record : imRecords) {
//                MsgItem msgItem = imRecordService.getMsgItem(shopSessionInfo, userSessionInfo, record);
//                msgItems.add(msgItem);
//            }
//
//            // 发给前端聊天记录
//            session.getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.success(msgItems)));
//            // 看了和某人的聊天记录，将未读聊天记录变成已读
//            imRecordService.updateToRead(userSessionInfo.getUserId(), shopSessionInfo.getShopId(), 0);
//            return;
//        }

        MsgItem msgItem = imRecordService.getMsgItemByPlatform(sysSessionInfo, userSessionInfo, imRecord);

        // 发给用户聊天记录
        userSessionInfo.getSession().getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.success(msgItem)));
//        // 看了和某人的聊天记录，将未读聊天记录变成已读
//        imRecordService.updateToRead(userSessionInfo.getUserId(), shopSessionInfo.getShopId(), 0);

    }

    /**
     * 实现服务器主动推送
     */
    public static boolean sendMessage(Long shopId, MsgItem msgItem) {
        SysSessionInfo sysSessionInfo = SYS_MAP.get(shopId);
        if (sysSessionInfo == null) {
            return false;
        }
        try {
            sysSessionInfo.getSession().getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.success(msgItem)));
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }


}
